package com.example.demo.shengchan;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.mapper.IaWxKefuMsgMapper;
import com.example.demo.mapper.IaWxTmplMsgMapper;
import com.example.demo.model.IaWxKefuMsg;
import com.example.demo.model.IaWxTmplMsg;
import com.example.demo.utils.HttpUtils;
import com.example.demo.utils.RedisUtils;
import com.example.demo.utils.SerializeUtils;
import com.example.demo.utils.wx.KefuSendUtils;
import com.example.demo.utils.wx.WxConfig;
import com.example.demo.utils.wx.WxTemplateResult;
import com.example.demo.utils.wx.WxTemplateUtils;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
@RabbitListener(queues = "temp")
public class HelloReceiver1 {

    private static final Logger logger = LoggerFactory.getLogger(HelloReceiver1.class);


    @Resource
    private IaWxTmplMsgMapper iaWxTmplMsgMapper;
    @Resource
    private IaWxKefuMsgMapper iaWxKefuMsgMapper;

    @RabbitListener(queues = "temp")
    public void process(Message message, Channel channel) {
        sendTempl(message, channel);
    }

    @RabbitListener(queues = "temp")
    public void process1(Message message, Channel channel) {
        sendTempl(message, channel);
    }

    @RabbitListener(queues = "data")
    public void data(Message message, Channel channel) {
        sendData(message, channel);
    }

    @RabbitListener(queues = "data")
    public void data1(Message message, Channel channel) {
        sendData(message, channel);
    }

    @RabbitListener(queues = "keFuMsg")
    public void keFuMsg(Message message, Channel channel) {
        sendKefuMsg(message, channel);
    }

    @RabbitListener(queues = "keFuMsg")
    public void keFuMsg1(Message message, Channel channel) {
        sendKefuMsg(message, channel);
    }

    @RabbitListener(queues = "h")
    public void hMsg(Message message, Channel channel) {
        sendHour(message, channel);
    }

    @RabbitListener(queues = "h")
    public void hMsg1(Message message, Channel channel) {
        sendHour(message, channel);
    }

    /**
     * 消费模板消息
     */
    private void sendTempl(Message message, Channel channel) {
        String tmpId = "";
        long total = 0;
        String openId = null;
        try {
            boolean flag = false;
            JSONObject map = (JSONObject) JSON.parse(message.getBody());
            if (map == null) {
                logger.error("map为空！自动消费！");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            total = Long.valueOf(map.get("total").toString());// 可能存在并发问题，设置误差10个人
            tmpId = map.get("tmpId").toString();
            openId = map.get("openId").toString();
            String nickName = map.get("nickName").toString();
            if (RedisUtils.get(tmpId + "obj") == null) {
                RedisUtils.set(tmpId + "obj", iaWxTmplMsgMapper.selectById(tmpId), 14400);
            }
            IaWxTmplMsg iaWxTmplMsg = (IaWxTmplMsg) RedisUtils.get(tmpId + "obj");
            String url = iaWxTmplMsg.getUrl();
            String data = iaWxTmplMsg.getData();
            String pushTmpl = iaWxTmplMsg.getPushTmpl();
            /* 检查redis 推送状态  0-不推送，1-定时推送，2-推送中，3-暂停推送，4-取消推送，5-推送结束 */
            if (RedisUtils.get(tmpId) != null) {
                String status = RedisUtils.get(tmpId).toString();
                /* 暂停 */
                if ("3".equals(status)) {
                    for (int i = 0; i < 9999999; i++) {
                        if (RedisUtils.get(tmpId) != null && RedisUtils.get(tmpId).toString().equals("3")) {
                            flag = true;
                            Thread.sleep(60000);
                            logger.info("-------------暂停推送,当前第" + i + "次睡眠-------" + new Date());
                        } else {
                            logger.info("break");
                            break;
                        }
                    }
                }
                /* 取消 */
                if (RedisUtils.get(tmpId) != null && RedisUtils.get(tmpId).toString().equals("4")) {
                    if (RedisUtils.get(tmpId + "_status") != null) {
                        String status_q = RedisUtils.get(tmpId + "_status").toString();
                        if (status_q.equals("1")) {
                            /* 已取消，返回所有后续消费 */
                            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                            return;
                        }
                    }
                    RedisUtils.set(tmpId + "_status", "1", 7200);
                    logger.info("-------------停止推送-------" + new Date());
                    iaWxTmplMsg.setId(tmpId);
                    iaWxTmplMsg.setEndTime(new Date());
                    iaWxTmplMsg.setStatus(4);
                    iaWxTmplMsgMapper.updateById(iaWxTmplMsg);
                    return;
                }
            }
            /* 推送 */
            if (flag) {
                IaWxTmplMsg wxTmplMsg = iaWxTmplMsgMapper.selectById(tmpId);
                RedisUtils.set(tmpId + "obj", iaWxTmplMsgMapper.selectById(tmpId), 14400);
                url = wxTmplMsg.getUrl();
                data = wxTmplMsg.getData();
                pushTmpl = wxTmplMsg.getPushTmpl();
            }
            logger.info("======== user =======");
            String token = HttpUtils.getAccessToken();
            WxTemplateResult sendTimeerMsg;
            try {
                sendTimeerMsg = WxTemplateUtils.sendTimeerMsg(nickName, openId, token, data, url, pushTmpl);
                if (sendTimeerMsg == null || !sendTimeerMsg.isSuccess()) {
                    if (iaWxTmplMsgMapper.updateTemplNum(tmpId, "0", total) < 1) {
                        logger.error(openId + "：：当前更新失败次数失败");
                    }
                } else {
                    logger.info("::success");
                    if (iaWxTmplMsgMapper.updateTemplNum(tmpId, "1", total) < 1) {
                        logger.error(openId + "：：当前更新成功次数失败");
                    }
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
                if (iaWxTmplMsgMapper.updateTemplNum(tmpId, "0", total) < 1) {
                    logger.error(openId + "：：当前更新失败次数失败");
                }
            } finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("==========================已手动确认消费,消息为" + new String(message.getBody()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (iaWxTmplMsgMapper.updateTemplNum(tmpId, "0", total) < 1) {
                    /* 这里如果失败，那么在 50 52 就抛出了异常*/
                    logger.error(openId + "：：当前更新失败次数失败");
                }
                /* 抛出异常，视为消费消息，防止消息重复消费 */
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("异常报错!");
            } catch (IOException ee) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 消费36-48小时未互动用户推送
     */
    private void sendHour(Message message,Channel channel){
        long total = 0;
        String openId = null;
        String nickName= null;
        String id = null;
        String desc = "NAME 老师，很抱歉，由于微信限制，长时间未与公众号互动，您将收不到我们的免费素材、动画访客浏览通知推送服务。\n\n\uD83D\uDC49<a href='weixin://bizmsgmenu?msgmenucontent=取消限制&msgmenuid=1'>点我取消限制</a>";
        try {
            JSONObject map = (JSONObject) JSON.parse(message.getBody());
            if (map == null) {
                logger.error("map为空！24H自动消费！");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            total = Long.valueOf(map.get("total").toString());// 可能存在并发问题，设置误差10个人
            openId = map.get("openId").toString();
            nickName = map.get("nickName").toString();
            id = map.get("id").toString();
            logger.info("======== start =======");
            try {
                desc = desc.replace("NAME",nickName);
                boolean b = KefuSendUtils.keFuHourSendByOpenId(openId, desc);
                if (b) {
                    logger.info("::success");
                    if (iaWxTmplMsgMapper.updateHNum(id, "1", total) < 1) {
                        logger.error(openId + "：：当前更新成功次数失败");
                    }
                } else {
                    if (iaWxTmplMsgMapper.updateHNum(id, "0", total) < 1) {
                        logger.error(openId + "：：当前更新失败次数失败");
                    }
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
                if (iaWxTmplMsgMapper.updateHNum(id, "0", total) < 1) {
                    logger.error(openId + "：：当前更新失败次数失败");
                }
            } finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("==========================已手动确认消费,消息为" + new String(message.getBody()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (iaWxTmplMsgMapper.updateHNum(id, "0", total) < 1) {
                    /* 这里如果失败，那么在 50 52 就抛出了异常*/
                    logger.error(openId + "：：当前更新24H失败次数失败");
                }
                /* 抛出异常，视为消费消息，防止消息重复消费 */
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("异常报错!");
            } catch (IOException ee) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 消费数据统计推送
     */
    private void sendData(Message message, Channel channel) {
        String readTimes = "";
        String shareTimes = "";
        String templId = "";
        String nickName = "";
        long total = 0;
        String openId = null;
        try {
            JSONObject map = (JSONObject) JSON.parse(message.getBody());
            if (map == null) {
                logger.error("map为空！自动消费！");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            total = Long.valueOf(map.get("total").toString());// 可能存在并发问题，设置误差10个人
            shareTimes = map.get("shareTimes").toString();
            templId = map.get("templId").toString();
            readTimes = map.get("readTimes").toString();
            openId = map.get("openId").toString();
            nickName = map.get("nickName").toString();
            logger.info("======== start =======");
            String token = HttpUtils.getAccessToken();
            WxTemplateResult sendTimeerMsg;
            try {
                sendTimeerMsg = WxTemplateUtils.sendData(openId, shareTimes, readTimes, nickName,token);
                if (sendTimeerMsg == null || !sendTimeerMsg.isSuccess()) {
                    if (iaWxTmplMsgMapper.updateDataNum(templId, "0", total) < 1) {
                        logger.error(openId + "：：当前更新失败次数失败");
                    }
                } else {
                    logger.info("::success");
                    if (iaWxTmplMsgMapper.updateDataNum(templId, "1", total) < 1) {
                        logger.error(openId + "：：当前更新成功次数失败");
                    }
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
                if (iaWxTmplMsgMapper.updateDataNum(templId, "0", total) < 1) {
                    logger.error(openId + "：：当前更新失败次数失败");
                }
            } finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("==========================已手动确认消费,消息为" + new String(message.getBody()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (iaWxTmplMsgMapper.updateDataNum(templId, "0", total) < 1) {
                    /* 这里如果失败，那么在 50 52 就抛出了异常*/
                    logger.error(openId + "：：当前更新失败次数失败");
                }
                /* 抛出异常，视为消费消息，防止消息重复消费 */
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("异常报错!");
            } catch (IOException ee) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 消费客服消息推送
     */
    private void sendKefuMsg(Message message, Channel channel) {
        String id = null;
        String openId = null;
        long total = 0;
        try {
            boolean flag = false;
            JSONObject map = (JSONObject) JSON.parse(message.getBody());
            if (map == null) {
                logger.error("map为空！自动消费！");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            String msgType = map.get("msgType").toString();
            total = Long.valueOf(map.get("total").toString());// 可能存在并发问题，设置误差10个人
            String artJson = map.get("artJson") == null ? "" : map.get("artJson").toString();
            String txtJson = map.get("txtJson") == null ? "" : map.get("txtJson").toString();
            String imgJson = map.get("imgJson") == null ? "" : map.get("imgJson").toString();
            id = map.get("id") == null ? "" : map.get("id").toString();
            openId = map.get("openId") == null ? "" : map.get("openId").toString();
            /* 暂停 */
            if (RedisUtils.get(id) != null && RedisUtils.get(id).toString().equals("3")) {
                for (int i = 0; i < 9999999; i++) {
                    if (RedisUtils.get(id) != null && RedisUtils.get(id).toString().equals("3")) {
                        try {
                            Thread.sleep(60000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("-------------暂停图文推送,当前第" + i + "次睡眠-------" + new Date());
                        flag = true;
                    } else {
                        System.out.println("break");
                        break;
                    }
                }
            }
            if (RedisUtils.get(id) != null && RedisUtils.get(id).toString().equals("4")) {
                if (RedisUtils.get(id + "_status") != null) {
                    if ("1".equals(RedisUtils.get(id + "_status").toString())) {
                        /* 已取消，返回所有后续消费 */
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        return;
                    }
                }
                logger.info("-------------停止推送-------" + new Date());
                RedisUtils.set(id + "_status", "1", 7200);
                IaWxKefuMsg iaWxKefuMsg1 = new IaWxKefuMsg();
                iaWxKefuMsg1.setId(id);
                iaWxKefuMsg1.setKefuStatus("4");
                iaWxKefuMsgMapper.updateById(iaWxKefuMsg1);
                logger.info("已取消推送::::");
                return;
            }
            if (flag) {
                IaWxKefuMsg iaWxKefuMsg = iaWxKefuMsgMapper.selectById(id);
                msgType = iaWxKefuMsg.getType();
                Map<String, String> newMap = map(msgType, iaWxKefuMsg);
                artJson = newMap.get("ar");
                txtJson = newMap.get("tx");
                imgJson = newMap.get("im");
            }
            /* 开始发送 */
            try {
                if ("0".equals(msgType)) {
                    if (KefuSendUtils.wenZhangSendByOpenId(openId, artJson)) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
                if ("1".equals(msgType)) {
                    if (KefuSendUtils.keFuSendByOpenId(openId, txtJson)) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
                if ("2".equals(msgType)) {
                    boolean wenz = KefuSendUtils.wenZhangSendByOpenId(openId, artJson);
                    boolean txt = KefuSendUtils.keFuSendByOpenId(openId, txtJson);
                    if (wenz && txt) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
                if ("3".equals(msgType)) {
                    boolean img = KefuSendUtils.keFuImagesSendByOpenId(openId, imgJson);
                    if (img) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
                if ("4".equals(msgType)) {
                    boolean img = KefuSendUtils.keFuImagesSendByOpenId(openId, imgJson);
                    boolean txt = KefuSendUtils.keFuSendByOpenId(openId, txtJson);
                    if (img && txt) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) == 0) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
                if ("5".equals(msgType)) {
                    boolean art = KefuSendUtils.wenZhangSendByOpenId(openId, artJson);
                    boolean img = KefuSendUtils.keFuImagesSendByOpenId(openId, imgJson);
                    if (img && art) {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "1", total) < 1) {
                            logger.error(openId + "：：当前更新成功次数失败");
                        }
                    } else {
                        if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) == 0) {
                            logger.error(openId + "：：当前更新失败次数失败");
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                    logger.error(openId + "：：当前更新失败次数失败");
                }
            } finally {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("==========================已手动确认消费,消息为" + new String(message.getBody()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (iaWxKefuMsgMapper.updateKeFuMsgNum(id, "0", total) < 1) {
                    /* 这里如果失败，那么在 还没发出去 就抛出了异常*/
                    logger.error(openId + "：：当前更新失败次数失败");
                }
                /* 抛出异常，视为消费消息，防止消息重复消费 */
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.info("异常报错!");
            } catch (IOException ee) {
                e.printStackTrace();
            }
        }
    }

    private Map<String, String> map(String msgType, IaWxKefuMsg iaWxKefuMsg) {
        // 0 文章  1 文本 3 图片 2 文章+文本 4 图片+文本 5 文章+图片
        String artJson;
        String txtJson ;
        String imgJson;
        Map<String, String> map = new HashMap<>();
        if ("0".equals(msgType) || "2".equals(msgType) || "5".equals(msgType)) {
            artJson = KefuSendUtils.wenZhangSendByDesc(iaWxKefuMsg.getArtTitle(), iaWxKefuMsg.getArtDesc(), iaWxKefuMsg.getArtLink(), iaWxKefuMsg.getArtPic());
            map.put("ar", artJson);
        }
        if ("1".equals(msgType) || "2".equals(msgType) || "4".equals(msgType)) {
            StringBuilder main = new StringBuilder();
            StringBuilder s1 = new StringBuilder();
            StringBuilder s2 = new StringBuilder();
            StringBuilder s3 = new StringBuilder();
            StringBuilder s4 = new StringBuilder();
            StringBuilder s5 = new StringBuilder();
            iaWxKefuMsg = linkToHref(iaWxKefuMsg);
            s1.append(iaWxKefuMsg.getOneTxtTop()).append(iaWxKefuMsg.getOneTxt());
            s2.append(iaWxKefuMsg.getTwoTxtTop()).append(iaWxKefuMsg.getTwoTxt());
            s3.append(iaWxKefuMsg.getThreeTxtTop()).append(iaWxKefuMsg.getThreeTxt());
            s4.append(iaWxKefuMsg.getFourTxtTop()).append(iaWxKefuMsg.getFourTxt());
            s5.append(iaWxKefuMsg.getFiveTxtTop()).append(iaWxKefuMsg.getFiveTxt());
            if (s1.length() != 0) {
                main.append(s1).append("\n\n");
            }
            if (s2.length() != 0) {
                main.append(s2).append("\n\n");
            }
            if (s3.length() != 0) {
                main.append(s3).append("\n\n");
            }
            if (s4.length() != 0) {
                main.append(s4).append("\n\n");
            }
            if (s5.length() != 0) {
                main.append(s5).append("\n\n");
            }
            if (main.length() != 0) {
                txtJson = KefuSendUtils.keFuSendByDesc(main.toString());
                map.put("tx", txtJson);
            } else {
                logger.error("整理文字失败");
            }
        }
        if ("3".equals(msgType) || "4".equals(msgType) || "5".equals(msgType)) {
            imgJson = KefuSendUtils.keFuImagesSendByDesc(iaWxKefuMsg.getPicTxt());
            map.put("im", imgJson);
        }
        return map;
    }

    private static IaWxKefuMsg linkToHref(IaWxKefuMsg s) {
        if (StringUtils.isNotBlank(s.getOneTxtLink())) {
            s.setOneTxt("<a href='" + s.getOneTxtLink() + "'>" + s.getOneTxt() + "</a>");
        }
        if (StringUtils.isNotBlank(s.getTwoTxtLink())) {
            s.setTwoTxt("<a href='" + s.getTwoTxtLink() + "'>" + s.getTwoTxt() + "</a>");
        }
        if (StringUtils.isNotBlank(s.getThreeTxtLink())) {
            s.setThreeTxt("<a href='" + s.getThreeTxtLink() + "'>" + s.getThreeTxt() + "</a>");
        }
        if (StringUtils.isNotBlank(s.getFourTxtLink())) {
            s.setFourTxt("<a href='" + s.getFourTxtLink() + "'>" + s.getFourTxt() + "</a>");
        }
        if (StringUtils.isNotBlank(s.getFiveTxtLink())) {
            s.setFiveTxt("<a href='" + s.getFiveTxtLink() + "'>" + s.getFiveTxt() + "</a>");
        }
        return s;
    }


    public static void main(String[] args) {
        String json = "{" +
                "\"touser\":\"6c3bcbc711d549d6afcdb67fef0d9841\"," +
                "\"template_id\":\"c5pp3brlfAvsyw1Xd8a_sw8DuuSAWLfyLNkgxQhkGqU\"," +
                "\"url\":\"http://one.wcwlvip.com/\"," +
                "\"topcolor\":\"#FF0000\"," +
                "\"data\":{" +
                "\"first\": {" +
                "\"value\":\"111\"," +
                "\"color\":\"#173177\"" +
                "}," +
                "\"Good\":{" +
                "\"value\":\"222\"," +
                "\"color\":\"#173177\"" +
                "}," +
                "\"contentType\":{" +
                "\"value\":\"0426\"," +
                "\"color\":\"#173177\"" +
                "}," +
                "\"remark\":{" +
                "\"value\":\"消费\"," +
                "\"color\":\"#173177\"" +
                "}" +
                "}" +
                "}";
        try {
            String result = HttpUtils.doPostJson(WxConfig.TEMPLATE_SEND_URL.replace("ACCESS_TOKEN", "20_c6XRAbDzHC3_P5odfiWwU430JJwEXTRBrq7a4cUSlEaiOFMi28fc0XywLAiwbCK9lsYZk6dv3aIkB7yFGuXUDsbQd8w8mm3j-E_YmHfRJ6RUtbC9A7b2zpLzVtD8EYkwfLC_onsqESh-YJhJDNDaACARBRppppp"), json);
            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
